<?php

namespace app\admin\controller;


use app\common\model\RegSourceModel;
use app\common\model\StatUserModel;
use app\common\model\AppDownloadModel;
use think\Db;
use think\facade\Request;
use think\Validate;

class RegsourceController extends BaseController
{

    public function index()
    {
        return $this->fetch();
    }

    /**
     * 添加
     * @return mixed|\think\response\Json
     */
    public function add()
    {
        if (Request::isAjax()) {
            $all_param = Request::param();

            $validate = new Validate([
                'source_name' => 'require|length:2,20|chsDash',
                'device'      => 'require|integer|in:1,2,3',
                'description' => 'length:0,100',
                'status'      => 'require|integer|in:0,1',
            ], [
                "source_name.require" => "渠道名称不能为空",
                "source_name.length"  => "渠道名称在2-20个字符",
                "source_name.chsDash" => "渠道名称中文、英文、_和-组成",
                "device"              => "请正确选择设备",
                "description.length"  => "描述不得超过100个字符",
                "status"              => "请正确选择状态",
            ]);
            if (!$validate->check($all_param)) {
                return self::bulidFail($validate->getError());
            }

            $reg_source_model = new RegSourceModel($all_param);

            if ($reg_source_model->device == 3) {
                if (empty($reg_source_model->url)) {
                    return self::bulidFail('请输入网址');
                }

                if (stripos($reg_source_model->url, 'http://') !== false || stripos($reg_source_model->url, 'https://') !== false) {
                    return self::bulidFail('请输入正确网址，不带http://或https://(示例：www.abc.com)');
                }

                // 查询url是否存在
                $c_where = [
                    ['url', '=', $all_param['url']],
                ];
                if (RegSourceModel::where($c_where)->field('id')->find()) {
                    return self::bulidFail('网址已存在，请更换其他网址');
                }
            }

            $reg_source_model->create_time = date('Y-m-d H:i:s');
            $reg_source_model->source_key  = $this->createSourceKey();

            // 初始化当天统计信息
            $stat_user_data = [
                'source_key'  => $reg_source_model->source_key,
                'date'        => date('Y-m-d'),
                'source_name' => $reg_source_model->source_name,
            ];

            Db::startTrans();
            try {
                if (!$reg_source_model->save()) {
                    throw new \Exception('添加失败');
                }

                if (StatUserModel::insertGetId($stat_user_data) < 1) {
                    throw new \Exception('添加失败');
                }

                // 记录日志
                $log_content = "添加渠道信息，ID：{$reg_source_model->id}，渠道标识：{$reg_source_model->source_key}";
                parent::addAdminLog($log_content);

                Db::commit();
                return self::bulidSuccess();
            } catch (\Exception $e) {
                Db::rollback();
                echo $e->getMessage();
            }
            return self::bulidFail('添加失败');
        }
        return $this->fetch();
    }

    /**
     * 编辑
     * @return mixed|\think\response\Json
     */
    public function edit()
    {
        if (Request::isAjax()) {
            $all_param = Request::param();

            $validate = new Validate([
                'id'          => 'require|integer|gt:0',
                'source_name' => 'require|length:2,20|chsDash',
                'description' => 'length:0,100',
                'status'      => 'require|integer|in:0,1',
            ], [
                'id'                  => '参数错误',
                "source_name.require" => "渠道名称不能为空",
                "source_name.length"  => "渠道名称在2-20个字符",
                "source_name.chsDash" => "渠道名称中文、英文、_和-组成",
                "description.length"  => "描述不得超过100个字符",
                "status"              => "请正确选择状态",
            ]);
            if (!$validate->check($all_param)) {
                return self::bulidFail($validate->getError());
            }

            $reg_source_model = RegSourceModel::get($all_param['id']);
            if (!$reg_source_model) {
                return self::bulidFail("信息不存在");
            }

            if ($reg_source_model->device == 3) {
                if (empty($all_param['url'])) {
                    return self::bulidFail('请输入网址');
                }

                if (stripos($all_param['url'], 'http://') !== false || stripos($all_param['url'], 'https://') !== false) {
                    return self::bulidFail('请输入正确网址，不带http://或https://(示例：www.abc.com)');
                }

                // 查询url是否存在
                $c_where = [
                    ['id', '<>', $all_param['id']],
                    ['url', '=', $all_param['url']],
                ];
                if (RegSourceModel::where($c_where)->field('id')->find()) {
                    return self::bulidFail('网址已存在，请更换其他网址');
                }
            } else {
                $reg_source_model->url = '';
            }

            $reg_source_model->update_time = date('Y-m-d H:i:s');

            if ($reg_source_model->save($all_param)) {
                //删除特殊渠道配置
                redis_del("SOURCE_SPEC:" . $reg_source_model->source_key);
                redis_del('go_webapi_ConfigPubSpec');
                //删除悦动圈渠道配置
                redis_del("SOURCE_JOYCIRCLE:" . $reg_source_model->source_key);
                redis_del('go_webapi_ConfigPubJoycircle');
                // 记录日志
                $log_content = "编辑渠道信息，ID：{$reg_source_model->id}，渠道标识：{$reg_source_model->source_key}";
                parent::addAdminLog($log_content);

                return self::bulidSuccess();
            }
            return self::bulidFail();
        }

        $id   = Request::param('id');
        $info = RegSourceModel::get($id);
        $this->assign("info", $info);
        return $this->fetch();
    }

    /**
     * 渠道列表
     * @return \think\response\Json
     */
    public function getlist()
    {
        $page        = Request::param("page");
        $limit       = Request::param("limit");
        $source_key  = Request::param('source_key');
        $source_name = Request::param('source_name');
        $status      = Request::param('status');
        $device      = Request::param('device');

        $where = [];
        if ($source_key) {
            $where[] = ['source_key', '=', $source_key];
        }
        if (is_numeric($status)) {
            $where[] = ['status', '=', $status];
        }
        if (is_numeric($device)) {
            $where[] = ['device', '=', $device];
        }
        if ($source_name) {
            $where[] = ['source_name', 'like', "%{$source_name}%"];
        }

        $list = RegSourceModel::with(
            [

                'appdownload' => function ($query) {
                    $query->field('count(id) as total,source')->group('source');
                }
            ]
        )->where($where)
            ->limit(($page - 1) * $limit, $limit)
            ->order("id", "desc")
            ->select();

        if (count($list) > 0) {
            $count = RegSourceModel::where($where)->count();

            $source_keys = array_column($list->toArray(), 'source_key');

            $field       = 'id,source_key,sum(register) as register,sum(valid_user) as valid_user';
            $statis_user = StatUserModel::field($field)
                ->whereIn('source_key', $source_keys)
                ->group('source_key')
                ->select()->toArray();
            $statis_user = array_column($statis_user, null, 'source_key');

            // 统计今日留存用户和昨日登录用户
            $field            = 'source_key,next_day_user,last_day_loggin';
            $statis_keep_data = StatUserModel::field($field)
                ->where(
                    [
                        ['source_key', 'in', $source_keys],
                        ['next_day_user', '>', 0],
                        ['last_day_loggin', '>', 0],
                    ]
                )->select();

            $statis_keep_perc = array();
            foreach ($statis_keep_data as $keep_info) {
                $perc = 0;
                if ($keep_info->last_day_loggin > 0) {
                    $perc = bcdiv($keep_info->next_day_user, $keep_info->last_day_loggin, 4);
                }
                if (isset($statis_keep_perc[$keep_info->source_key])) {
                    $statis_keep_perc[$keep_info->source_key] += $perc;
                } else {
                    $statis_keep_perc[$keep_info->source_key] = $perc;
                }
            }

            // 统计平均留存率-天数统计
            $keep_total_days = StatUserModel::field('source_key,count(id) as count')
                ->whereIn('source_key', $source_keys)
                ->group('source_key')
                ->select()->toArray();
            $keep_total_days = array_column($keep_total_days, 'count', 'source_key');

            // 计算平均留存率
            foreach ($statis_user as &$val) {
                $keep_perc        = isset($statis_keep_perc[$val['source_key']]) ? $statis_keep_perc[$val['source_key']] : 0;
                $keep_days        = isset($keep_total_days[$val['source_key']]) ? $keep_total_days[$val['source_key']] : 0;
                $val['retention'] = $keep_days > 0 ? round(($keep_perc / $keep_days) * 100, 2) : 0;
            }

            // 重新组合数组
            foreach ($list as &$item) {
                $statis_info = isset($statis_user[$item->source_key]) ? $statis_user[$item->source_key] : [];
                if (empty($statis_info)) {
                    $item->register   = 0;
                    $item->valid_user = 0;
                    $item->retention  = 0;
                    continue;
                }
                $item->register   = $statis_info['register'];
                $item->valid_user = $statis_info['valid_user'];
                // 留存率
                $item->retention = $statis_info['retention'];
            }

            // 汇总统计
            $statis = [
                'register'   => StatUserModel::sum('register'),
                'valid_user' => StatUserModel::sum('valid_user'),
            ];

            return json(["code" => 0, "msg" => "", "data" => $list, 'statis' => $statis, "count" => $count]);
        }
        return self::bulidFail("未查询到相关数据");
    }

    /**
     * 每日数据
     * @return mixed
     */
    public function everyday()
    {
        $source_key = Request::param('source_key');
        $start_time = Request::param('start_time');
        $this->assign('source_key', $source_key);
        $this->assign('start_time', $start_time);
        return $this->fetch();
    }

    public function everyday_list()
    {
        $source_key = Request::param('source_key');
        $time_type  = Request::param("type");
        $start_time = Request::param("start_time");
        $end_time   = Request::param("end_time");

        $page  = Request::param("page");
        $limit = Request::param("limit");

        switch ($time_type) {
            case 0:
                $end_time = $end_time . ' 23:59:59';
                break;
            case 1:
                $start_time = date('Y-m-d', time());
                $end_time = date('Y-m-d 23:59:59', time());
                break;
            case 2:
                // 昨日
                $start_time = date('Y-m-d', strtotime('-1 day'));
                $end_time   = date('Y-m-d 23:59:59', strtotime($start_time));
                break;
            case 3:
                // 本周
                $w          = date('w', time());
                $start_time = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d') - $w + 1, date('Y')));
                $end_time   = date('Y-m-d 23:59:59', mktime(0, 0, 0, date('m'), date('d') + (7 - $w), date('Y')));
                break;

            case 4:
                // 本月
                $start_time = date('Y-m-d', mktime(0, 0, 0, date('m'), 1, date('Y')));
                $end_time   = date('Y-m-d 23:59:59', mktime(23, 59, 59, date('m'), date('t'), date('Y')));
                break;
            case 5:
                // 最近30天
                $start_time = date('Y-m-d', strtotime('-29 days'));
                break;
            case 6:
                // 上个月
                $start_time = date("Y-m-d", mktime(0, 0, 0, date("m") - 1, 1, date("Y")));
                $end_time   = date("Y-m-d 23:59:59", mktime(23, 59, 59, date("m"), 0, date("Y")));
                break;
        }

        $where = [];
        if ($source_key) {
            $where[] = ['source_key', '=', $source_key];
        }
        if ($start_time) {
            $where[] = ['date', '>=', $start_time];
        }
        if ($end_time) {
            $where[] = ['date', '<=', $end_time];
        }


        $list = StatUserModel::with('regsource')->where($where)
            ->limit(($page - 1) * $limit, $limit)
            ->order("date", "desc")
            ->select();


        if (count($list) > 0) {
            $count = StatUserModel::where($where)->count();

            foreach ($list as &$item) {
                // 查询昨日登录用户
                $y_day = date('Y-m-d', strtotime('-1 day', strtotime($item->date)));
                // 留存率
                $item->retention = $item->last_day_loggin > 0 ? round(($item->next_day_user / $item->last_day_loggin) * 100, 2) : 0;
                // 下载量
                $dlwhere = [];
                $dlwhere[] = ['source', '=', $item['source_key']];
                $day_s = date('Y-m-d', strtotime($item->date));
                $dlwhere[] = ['time', '>=', $day_s];
                $dlwhere[] = ['time', '<=', $day_s . ' 23:59:59'];
                // var_dump($dlwhere);
                $item->dlcount = AppDownloadModel::where($dlwhere)->count('id');
                // echo AppDownloadModel::getLastSql();
            }

            $field        = "sum(register) as register,sum(valid_user) as valid_user,sum(loggin_user) as loggin_user,sum(active_user) as active_user";
            $statis_model = StatUserModel::where($where)->field($field)->find();

            $statis_dlwhere = [];
            $statis_dlwhere[] = ['source', '=', $source_key];
            if ($start_time) {
                $statis_dlwhere[] = ['time', '>=', $start_time];
            }
            if ($end_time) {
                $statis_dlwhere[] = ['time', '<=', $end_time];
            }

            // 汇总统计
            $statis = [
                'dl_count' => AppDownloadModel::where($statis_dlwhere)->count('id'),
                'count_days'  => StatUserModel::where($where)->group('date')->count(),
                'register'    => isset($statis_model->register) ? $statis_model->register : 0,
                'valid_user'  => isset($statis_model->valid_user) ? $statis_model->valid_user : 0,
                'loggin_user' => isset($statis_model->loggin_user) ? $statis_model->loggin_user : 0,
                'active_user' => isset($statis_model->active_user) ? $statis_model->active_user : 0,
            ];

            // echo AppDownloadModel::getLastSql();

            return json(["code" => 0, "msg" => "", "data" => $list, 'statis' => $statis, "count" => $count]);
        }
        return self::bulidFail("未查询到相关数据");
    }


    /**
     * 批量封禁
     * @return \think\response\Json
     */
    public function frozen()
    {
        $ids = Request::param('ids');
        if (empty($ids)) {
            return self::bulidFail('参数错误，请重试');
        }

        $res = RegSourceModel::whereIn('id', $ids)->update(['status' => 0]);

        if ($res) {
            return self::bulidSuccess([]);
        }
        return self::bulidFail();
    }

    /**
     * 封禁解封
     * @return \think\response\Json
     */
    public function set_status()
    {
        $id     = Request::param('id');
        $status = Request::param('status');
        if (!in_array($status, [0, 1])) {
            return self::bulidFail("参数错误");
        }

        $reg_source = RegSourceModel::get($id);
        if (!$reg_source) {
            return self::bulidFail("信息不存在");
        }

        $reg_source->status = $status;
        if ($reg_source->save()) {
            // 记录日志
            $log_content = ($reg_source->status == 1 ? '解封' : '封禁') . "渠道，ID：{$reg_source->id}";
            parent::addAdminLog($log_content);

            return self::bulidSuccess();
        }
        return self::bulidFail();
    }

    /**
     * 渠道统计报表
     * @return mixed
     */
    public function report()
    {
        if (Request::isAjax()) {
            $time_type  = Request::param("type");
            $start_time = Request::param("start_time");
            $end_time   = Request::param("end_time");

            $page  = Request::param("page");
            $limit = Request::param("limit");


            switch ($time_type) {
                case 1:
                    $start_time = date('Y-m-d', time());
                    break;
                case 2:
                    // 昨日
                    $start_time = date('Y-m-d', strtotime('-1 day'));
                    $end_time   = date('Y-m-d', strtotime($start_time));
                    break;
                case 3:
                    // 本周
                    $w          = date('w', time());
                    $start_time = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d') - $w + 1, date('Y')));
                    $end_time   = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d') + (7 - $w), date('Y')));
                    break;

                case 4:
                    // 本月
                    $start_time = date('Y-m-d', mktime(0, 0, 0, date('m'), 1, date('Y')));
                    $end_time   = date('Y-m-d', mktime(23, 59, 59, date('m'), date('t'), date('Y')));
                    break;
                case 5:
                    // 最近30天
                    $start_time = date('Y-m-d', strtotime('-29 days'));
                    break;
                case 6:
                    // 上个月
                    $start_time = date("Y-m-d", mktime(0, 0, 0, date("m") - 1, 1, date("Y")));
                    $end_time   = date("Y-m-d", mktime(23, 59, 59, date("m"), 0, date("Y")));
                    break;
            }

            $where = [];
            if ($start_time) {
                $where[] = ['date', '>=', $start_time];
            }
            if ($end_time) {
                $where[] = ['date', '<=', $end_time];
            }

            $field = "date,sum(register) as register,sum(valid_user) as valid_user,sum(loggin_user) as loggin_user,sum(active_user) as active_user,sum(next_day_user) as next_day_user";
            $list  = StatUserModel::with('regsource')->where($where)
                ->field($field)
                ->limit(($page - 1) * $limit, $limit)
                ->order("date", "desc")
                ->group('date')
                ->select();


            if (count($list) > 0) {
                $count = StatUserModel::where($where)->group('date')->count();

                foreach ($list as &$item) {
                    // 查询昨日登录用户
                    $y_day               = date('Y-m-d', strtotime('-1 day', strtotime($item->date)));
                    $yestorday_loginuser = StatUserModel::where('date', $y_day)->group('date')->sum('loggin_user');
                    // 留存率
                    $item->retention = $yestorday_loginuser > 0 ? round(($item->next_day_user / $yestorday_loginuser) * 100, 2) : 0;
                }


                $field        = "sum(register) as register,sum(valid_user) as valid_user,sum(loggin_user) as loggin_user,sum(active_user) as active_user";
                $statis_model = StatUserModel::where($where)->field($field)->find();
                // 汇总统计
                $statis = [
                    'register'    => isset($statis_model->register) ? $statis_model->register : 0,
                    'valid_user'  => isset($statis_model->valid_user) ? $statis_model->valid_user : 0,
                    'loggin_user' => isset($statis_model->loggin_user) ? $statis_model->loggin_user : 0,
                    'active_user' => isset($statis_model->active_user) ? $statis_model->active_user : 0,
                ];

                return json(["code" => 0, "msg" => "", "data" => $list, 'statis' => $statis, "count" => $count]);
            }
            return self::bulidFail("未查询到相关数据");
        }
        return $this->fetch();
    }

    /**
     * 生成唯一标识
     */
    protected function createSourceKey()
    {
        $str     = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $str_arr = str_split($str);
        shuffle($str_arr);

        $rand_keys = '';
        for ($i = 0; $i < 8; $i++) {
            $j         = rand(0, 35);
            $rand_keys .= $str_arr[$j];
        }

        //查询是否已存在
        if (RegSourceModel::where('source_key', $rand_keys)->find()) {
            return $this->createSourceKey();
        }
        return $rand_keys;
    }
    
    public function del()
    {
        $all_param = Request::param();

        $validate = new Validate([
            'id'          => 'require|integer|gt:0',
        ], [
            'id'                  => '参数错误',
        ]);
        if (!$validate->check($all_param)) {
            return self::bulidFail($validate->getError());
        }

        $reg_source_model = RegSourceModel::get($all_param['id']);
        if (!$reg_source_model) {
            return self::bulidFail("信息不存在");
        }

        if ($reg_source_model->delete()) {
            //删除特殊渠道配置
            redis_del("SOURCE_SPEC:" . $reg_source_model->source_key);
            redis_del('go_webapi_ConfigPubSpec');
            //删除悦动圈渠道配置
            redis_del("SOURCE_JOYCIRCLE:" . $reg_source_model->source_key);
            redis_del('go_webapi_ConfigPubJoycircle');
            // 记录日志
            $log_content = "删除渠道信息，ID：{$reg_source_model->id}，渠道标识：{$reg_source_model->source_key}";
            parent::addAdminLog($log_content);

            return self::bulidSuccess();
        }
        return self::bulidFail();
    }

}
